package com.example.thymeleaf.word.service.impl;

import com.aspose.words.*;
import com.example.thymeleaf.word.service.AsposeWordService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.Map;

@Service
public class AsposeWordServiceImpl implements AsposeWordService {
    private static final Logger LOGGER = LoggerFactory.getLogger(AsposeWordServiceImpl.class);
    @Resource
    private TemplateEngine templateEngine;

    /**
     * word下载
     *
     * @param templateName 模板名称
     * @param variables    模板参数集
     * @param response     HttpServletResponse
     * @param fileName     下载文件名称
     */
    public void download(String templateName, Map<String, Object> variables, HttpServletResponse response, String fileName) throws Exception {
        response.setHeader("content-type", "application/octet-stream");
        response.setContentType("application/octet-stream");
        response.setHeader("Content-Disposition", "attachment;fileName=" + URLEncoder.encode(fileName, "UTF-8"));
        
        Document document = getTemplateDocument(templateName, variables);
        writeOutputStream(document, response);
    }

    /**
     * word预览
     *
     * @param templateName 模板名称
     * @param variables    模板参数集
     * @param response     HttpServletResponse
     */
    public void preview(String templateName, Map<String, Object> variables, HttpServletResponse response) throws Exception {
        response.setContentType("application/vnd.openxmlformats-officedocument.wordprocessingml.document");
        Document document = getTemplateDocument(templateName, variables);
        writeOutputStream(document, response);
    }

    private void writeOutputStream(Document document, HttpServletResponse response) throws Exception {
        try (OutputStream outputStream = response.getOutputStream()) {
            document.save(outputStream, SaveFormat.DOCX);
        }
    }

    private Document getTemplateDocument(String templateName, Map<String, Object> variables) throws Exception {
        // 声明一个上下文对象，里面放入要存到模板里面的数据
        final Context context = new Context();
        context.setVariables(variables);
        String html = templateEngine.process(templateName, context);
        InputStream inputStream = new ByteArrayInputStream(html.getBytes());

        LoadOptions loadOptions = new LoadOptions();
        loadOptions.setLoadFormat(LoadFormat.HTML);
        return new Document(inputStream, loadOptions);
    }

}
